home *** CD-ROM | disk | FTP | other *** search
- #include "ztriangle.h"
-
- void renderTriangle(ZBuffer *zb, ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2, int color, int _drgbdx,
- PIXEL *texture, float fdzdx, float fndzdx, float ndszdx, float ndtzdx,
- char interp_z_d, char interp_rgb_d, char interp_st_d, char interp_stz_d,
- draw_init_t _draw_init, put_pixel_t _put_pixel, draw_line_t _draw_line) {
-
- ZBufferPoint *t, *pr1, *pr2, *l1, *l2;
- float fdx1, fdx2, fdy1, fdy2, fz, d1, d2;
- unsigned short *pz1;
- PIXEL *pp1;
- int part, update_left, update_right;
- int nb_lines, dx1, dy1, tmp, dx2, dy2;
- int error, derror;
- int x1, dxdy_min, dxdy_max;
-
- /* warning: x2 is multiplied by 2^16 */
- int x2, dx2dy2;
- int z1, dzdx, dzdy, dzdl_min, dzdl_max;
-
- int r1, drdx, drdy, drdl_min, drdl_max;
- int g1, dgdx, dgdy, dgdl_min, dgdl_max;
- int b1, dbdx, dbdy, dbdl_min, dbdl_max;
-
- int s1, dsdx, dsdy, dsdl_min, dsdl_max;
- int t1, dtdx, dtdy, dtdl_min, dtdl_max;
-
- float sz1, dszdx, dszdy, dszdl_min, dszdl_max;
- float tz1, dtzdx, dtzdy, dtzdl_min, dtzdl_max;
-
- /* we sort the vertex with increasing y */
- if(p1->y < p0->y) {
- t = p0;
- p0 = p1;
- p1 = t;
- }
-
- if(p2->y < p0->y) {
- t = p2;
- p2 = p1;
- p1 = p0;
- p0 = t;
- }
- else if(p2->y < p1->y) {
- t = p1;
- p1 = p2;
- p2 = t;
- }
-
- /* we compute dXdx and dXdy for all interpolated values */
- fdx1 = p1->x - p0->x;
- fdy1 = p1->y - p0->y;
-
- fdx2 = p2->x - p0->x;
- fdy2 = p2->y - p0->y;
-
- fz = fdx1 * fdy2 - fdx2 * fdy1;
- if(fz == 0) {
- return;
- }
-
- fz = 1.0 / fz;
-
- fdx1 *= fz;
- fdy1 *= fz;
- fdx2 *= fz;
- fdy2 *= fz;
-
- if(interp_z_d) {
- d1 = p1->z - p0->z;
- d2 = p2->z - p0->z;
- dzdx = (int) (fdy2 * d1 - fdy1 * d2);
- dzdy = (int) (fdx1 * d2 - fdx2 * d1);
- }
-
- if(interp_rgb_d) {
- d1 = p1->r - p0->r;
- d2 = p2->r - p0->r;
- drdx = (int) (fdy2 * d1 - fdy1 * d2);
- drdy = (int) (fdx1 * d2 - fdx2 * d1);
-
- d1 = p1->g - p0->g;
- d2 = p2->g - p0->g;
- dgdx = (int) (fdy2 * d1 - fdy1 * d2);
- dgdy = (int) (fdx1 * d2 - fdx2 * d1);
-
- d1 = p1->b - p0->b;
- d2 = p2->b - p0->b;
- dbdx = (int) (fdy2 * d1 - fdy1 * d2);
- dbdy = (int) (fdx1 * d2 - fdx2 * d1);
- }
-
- if(interp_st_d) {
- d1 = p1->s - p0->s;
- d2 = p2->s - p0->s;
- dsdx = (int) (fdy2 * d1 - fdy1 * d2);
- dsdy = (int) (fdx1 * d2 - fdx2 * d1);
-
- d1 = p1->t - p0->t;
- d2 = p2->t - p0->t;
- dtdx = (int) (fdy2 * d1 - fdy1 * d2);
- dtdy = (int) (fdx1 * d2 - fdx2 * d1);
- }
-
- if(interp_stz_d) { {
- float zz;
- zz = (float) p0->z;
- p0->sz = (float) p0->s * zz;
- p0->tz = (float) p0->t * zz;
- zz = (float) p1->z;
- p1->sz = (float) p1->s * zz;
- p1->tz = (float) p1->t * zz;
- zz = (float) p2->z;
- p2->sz = (float) p2->s * zz;
- p2->tz = (float) p2->t * zz;
-
- d1 = p1->sz - p0->sz;
- d2 = p2->sz - p0->sz;
- dszdx = (fdy2 * d1 - fdy1 * d2);
- dszdy = (fdx1 * d2 - fdx2 * d1);
-
- d1 = p1->tz - p0->tz;
- d2 = p2->tz - p0->tz;
- dtzdx = (fdy2 * d1 - fdy1 * d2);
- dtzdy = (fdx1 * d2 - fdx2 * d1);
- }
- }
-
- /* screen coordinates */
- pp1 = (PIXEL *) ((char *) zb->pbuf + zb->linesize * p0->y);
- pz1 = zb->zbuf + p0->y * zb->xsize;
-
- _draw_init(&_drgbdx, drdx, dgdx, dbdx, &color, p2, &fdzdx, &fndzdx, &ndszdx, &ndtzdx, texture,
- &dszdx, &dtzdx, zb, dzdx);
-
- for(part = 0; part < 2; part++) {
- if(part == 0) {
- if(fz > 0) {
- update_left = 1;
- update_right = 1;
- l1 = p0;
- l2 = p2;
- pr1 = p0;
- pr2 = p1;
- }
- else {
- update_left = 1;
- update_right = 1;
- l1 = p0;
- l2 = p1;
- pr1 = p0;
- pr2 = p2;
- }
-
- nb_lines = p1->y - p0->y;
- }
- else {
- /* second part */
- if(fz > 0) {
- update_left = 0;
- update_right = 1;
- pr1 = p1;
- pr2 = p2;
- }
- else {
- update_left = 1;
- update_right = 0;
- l1 = p1;
- l2 = p2;
- }
-
- nb_lines = p2->y - p1->y + 1;
- }
-
- /* compute the values for the left edge */
- if(update_left) {
- dy1 = l2->y - l1->y;
- dx1 = l2->x - l1->x;
- if(dy1 > 0) {
- tmp = (dx1 << 16) / dy1;
- }
- else {
- tmp = 0;
- }
-
- x1 = l1->x;
- error = 0;
- derror = tmp & 0x0000ffff;
- dxdy_min = tmp >> 16;
- dxdy_max = dxdy_min + 1;
-
- if(interp_z_d) {
- z1 = l1->z;
- dzdl_min = (dzdy + dzdx * dxdy_min);
- dzdl_max = dzdl_min + dzdx;
- }
-
- if(interp_rgb_d) {
- r1 = l1->r;
- drdl_min = (drdy + drdx * dxdy_min);
- drdl_max = drdl_min + drdx;
-
- g1 = l1->g;
- dgdl_min = (dgdy + dgdx * dxdy_min);
- dgdl_max = dgdl_min + dgdx;
-
- b1 = l1->b;
- dbdl_min = (dbdy + dbdx * dxdy_min);
- dbdl_max = dbdl_min + dbdx;
- }
-
- if(interp_st_d) {
- s1 = l1->s;
- dsdl_min = (dsdy + dsdx * dxdy_min);
- dsdl_max = dsdl_min + dsdx;
-
- t1 = l1->t;
- dtdl_min = (dtdy + dtdx * dxdy_min);
- dtdl_max = dtdl_min + dtdx;
- }
-
- if(interp_stz_d) {
- sz1 = l1->sz;
- dszdl_min = (dszdy + dszdx * dxdy_min);
- dszdl_max = dszdl_min + dszdx;
-
- tz1 = l1->tz;
- dtzdl_min = (dtzdy + dtzdx * dxdy_min);
- dtzdl_max = dtzdl_min + dtzdx;
- }
- }
-
- /* compute values for the right edge */
- if(update_right) {
- dx2 = (pr2->x - pr1->x);
- dy2 = (pr2->y - pr1->y);
- if(dy2 > 0) {
- dx2dy2 = (dx2 << 16) / dy2;
- }
- else {
- dx2dy2 = 0;
- }
-
- x2 = pr1->x << 16;
- }
-
- /* we draw all the scan line of the part */
- while(nb_lines > 0) {
- nb_lines--;
-
- if (_draw_line == NULL) {
- { /* generic draw line */
- register PIXEL *pp;
- register int n;
- register unsigned short *pz;
- unsigned int z, zz;
- register unsigned int or1, og1, ob1;
- unsigned int s, t;
- float sz, tz;
-
- // TODO: rgb???
- int rgb=0, drgbdx=0;
-
- n = (x2 >> 16) - x1;
- pp = (PIXEL *) ((char *) pp1 + x1 * PSZB);
-
- if(interp_z_d) {
- pz = pz1 + x1;
- z = z1;
- }
-
- if(interp_rgb_d) {
- or1 = r1;
- og1 = g1;
- ob1 = b1;
- }
-
- if(interp_st_d) {
- s = s1;
- t = t1;
- }
-
- if(interp_stz_d) {
- sz = sz1;
- tz = tz1;
- }
-
- while(n >= 3) {
- _put_pixel(0, &zz, pp, &tmp, &rgb, drgbdx, &z, pz, dzdx, color,
- texture, &s, &t, dsdx, dtdx);
- _put_pixel(1, &zz, pp, &tmp, &rgb, drgbdx, &z, pz, dzdx, color,
- texture, &s, &t, dsdx, dtdx);
- _put_pixel(2, &zz, pp, &tmp, &rgb, drgbdx, &z, pz, dzdx, color,
- texture, &s, &t, dsdx, dtdx);
- _put_pixel(3, &zz, pp, &tmp, &rgb, drgbdx, &z, pz, dzdx, color,
- texture, &s, &t, dsdx, dtdx);
-
- if(interp_z_d) {
- pz += 4;
- }
-
- pp = (PIXEL *) ((char *) pp + 4 * PSZB);
- n -= 4;
- }
-
- while(n >= 0) {
- _put_pixel(0, &zz, pp, &tmp, &rgb, drgbdx, &z, pz, dzdx, color,
- texture, &s, &t, dsdx, dtdx);
-
- if(interp_z_d) {
- pz += 1;
- }
-
- pp = (PIXEL *) ((char *) pp + PSZB);
- n -= 1;
- }
- }
- }
- else {
- _draw_line(dzdx, _drgbdx, r1, g1, b1, pz1, pp1, x1, x2, z1, sz1, tz1, dszdx, dtzdx,
- fdzdx, fndzdx, ndszdx, ndtzdx, texture);
- }
-
- /* left edge */
- error += derror;
- if(error > 0) {
- error -= 0x10000;
- x1 += dxdy_max;
-
- if(interp_z_d) {
- z1 += dzdl_max;
- }
-
- if(interp_rgb_d) {
- r1 += drdl_max;
- g1 += dgdl_max;
- b1 += dbdl_max;
- }
-
- if(interp_st_d) {
- s1 += dsdl_max;
- t1 += dtdl_max;
- }
-
- if(interp_stz_d) {
- sz1 += dszdl_max;
- tz1 += dtzdl_max;
- }
- }
- else {
- x1 += dxdy_min;
-
- if(interp_z_d) {
- z1 += dzdl_min;
- }
-
- if(interp_rgb_d) {
- r1 += drdl_min;
- g1 += dgdl_min;
- b1 += dbdl_min;
- }
-
- if(interp_st_d) {
- s1 += dsdl_min;
- t1 += dtdl_min;
- }
-
- if(interp_stz_d) {
- sz1 += dszdl_min;
- tz1 += dtzdl_min;
- }
- }
-
- /* right edge */
- x2 += dx2dy2;
-
- /* screen coordinates */
- pp1 = (PIXEL *) ((char *) pp1 + zb->linesize);
- pz1 += zb->xsize;
- }
- }
- }
-